package org.walklink.core.inject;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.walklink.common.exception.PluginInjectException;
import org.walklink.common.util.slidewin.DefaultSlideWinLimiter;

/**
 * 通用注入器
 *
 * @author lidishan
 */
public class CommonInject {

    private static final Logger LOGGER = LogManager.getLogger(CommonInject.class);

    private static volatile Injector pluginInjector;
    private static final Object LOCK = new Object();

    private static Injector getInjector() {
        if (pluginInjector == null) {
            // 双重检验锁
            synchronized (LOCK) {
                if (pluginInjector == null) {
                    try {
                        // 借用google的一个插件进行注入
                        pluginInjector = Guice.createInjector(new PluginModule());
                    } catch (Throwable ex) {
                        LOGGER.error("PluginInject init inject error", ex);
                        throw new PluginInjectException("PluginInject init inject error", ex);
                    }
                }
            }
        }

        return pluginInjector;
    }

    public static <T> T getInstance(Class<T> clazz) {
        try {
            return getInjector().getInstance(clazz);
        } catch (Throwable ex) {
            LOGGER.error("PluginInject getInstance load instance error", ex);
            throw new PluginInjectException("PluginInject getInstance load instance error", ex);
        }
    }

    private static class PluginModule extends AbstractModule {
        @Override
        protected void configure() {
             bind(DefaultSlideWinLimiter.class).in(Singleton.class);
        }
    }


}
